package com.ce.webframework.sec.dao.impl;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;


import com.ce.util.BlankUtil;
import com.ce.webframework.sec.dao.ISecDragSourceDao;
import com.ce.webframework.sec.model.SecDragSourceDO;
import com.ce.webframework.sec.model.SecDragSourceTempDO;
import com.ce.webframework.sec.model.SecDragTargetDO;
import com.ce.webframework.sec.model.SecShortcutDO;
import com.sitechasia.webx.core.dao.hibernate3.HibernateDomainObjectDao;

import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

public class SecDragSourceDaoImpl extends HibernateDomainObjectDao<SecDragSourceDO> implements ISecDragSourceDao {

    /**
     * 功能描述:通过用户标识、企业标识查询能显示的拖拉源数据集
     * @param userId 用户标识
     * @param funcEntityIds 权限标识 集合
     * @param epId 企业标识
     * @return SecDragSourceDO集合
     */
    @SuppressWarnings("unchecked")
    public List<SecDragSourceDO> getDragSources(Long userId, List<String> funcEntityIds ,Long epId){

    	String funcIdsSplit = "";
    	if	(funcEntityIds != null && funcEntityIds.size() > 0){

    		for(int i=0;i<funcEntityIds.size();i++){
    			String funcId = "'"+funcEntityIds.get(i).toString()+"'";
    			funcIdsSplit += funcId;

    			if (i!=funcEntityIds.size()-1){
    				funcIdsSplit+=",";
    			}
    		}
    	}



        StringBuffer hql = new StringBuffer();
        hql.append("FROM SecDragSourceDO info ");
        hql.append(" LEFT JOIN FETCH info.secDragTargetDO");
        hql.append(" LEFT JOIN FETCH info.secDragSourceTempDO");
        hql.append(" WHERE 1=1 ");
        if(!BlankUtil.isBlank(funcIdsSplit)){

        hql.append(" and info.secDragSourceTempDO.functionEntityId in (" + funcIdsSplit + ")");
        }
        hql.append(" AND info.userId =?");
//        hql.append(" WHERE info.userId =? AND info.type = ?");
        hql.append(" AND info.visible = '0' AND info.epId = ?");
        hql.append(" ORDER BY info.secDragTargetDO.dragTargetId DESC,");
        hql.append(" info.orderNum ASC");

        System.out.println("=========:" + hql.toString());

        Query query = getSession().createQuery(hql.toString());
        query.setParameter(0, userId);
        query.setParameter(1, epId);

        return query.list();

    }

    /**
     * 功能描述:删除拖动源
     * @param userId 用户标识
     * @param dragSourceId 拖动源标识
     * @return 无
     */
    public void deleteDragSource(Long userId, Long dragSourceId){

        SecDragSourceDO sds = this.findById(dragSourceId);
        //确定是不是当前用户操作，避免用非法方法删除其他用户数据
        if (sds.getUserId().equals(userId)){

        	StringBuffer hql = new StringBuffer();
        	hql.append("UPDATE SecDragSourceDO sds ");
        	hql.append("SET sds.orderNum = sds.orderNum - 1 ");
        	hql.append("WHERE sds.userId = ? ");
        	hql.append("AND sds.epId = ? ");
        	hql.append("AND sds.secDragTargetDO = ?");

        	Query query = getSession().createQuery(hql.toString());
        	query.setParameter(0, userId);
        	query.setParameter(1, sds.getEpId());
        	query.setParameter(2, sds.getSecDragTargetDO());

            this.doDelete(sds);
        }

    }

    /**
     * 功能描述:拖动源是否存在
     * @param userId 用户标识
     * @param dragSourceTempId 拖动源模板标识
     * @param epId 企业标识
     * @return boolean
     */
    public boolean isExist(Long userId, String dragSourceTempId, Long epId){

        Criteria crit = this.getEntityCriteria();
        crit.add(Restrictions.eq("userId", userId));
        crit.add(Restrictions.eq("secDragSourceTempDO.dragSourceTempId", Long.parseLong(dragSourceTempId)));
        crit.add(Restrictions.eq("epId", epId));

        if (crit.list() != null && crit.list().size() != 0){
            return true;
        } else {
            return false;
        }

    }

    /**
     * 功能描述:增加拖动源
     * @param userId 用户标识
     * @param dragTargetDO 容器对象
     * @param dragSourceTempDO 拖动源模板对象
     * @param orderNum 顺序号
     * @return 无
     */
    @SuppressWarnings("unchecked")
    public void addDragSource(Long userId, SecDragTargetDO dragTargetDO
            , SecDragSourceTempDO dragSourceTempDO, int orderNum){

    	int adjustOrderNum = this.adjustOrderNum(userId, dragSourceTempDO.getEpId()
    			, dragTargetDO.getDragTargetId(), orderNum);

        //把同一容器中大于当前顺序号的拖动源 +1
        StringBuffer hql = new StringBuffer();
        hql.append("UPDATE SecDragSourceDO sds ");
        hql.append("SET sds.orderNum = sds.orderNum + 1 ");
        hql.append("WHERE sds.secDragTargetDO = ? ");
        hql.append("AND sds.orderNum >= ? ");
        hql.append("AND sds.userId = ? ");
        hql.append("AND sds.epId = ? ");
        Query query = getSession().createQuery(hql.toString());
        query.setParameter(0, dragTargetDO);
        query.setParameter(1, adjustOrderNum);
        query.setParameter(2, userId);
        query.setParameter(3, dragSourceTempDO.getEpId());
        query.executeUpdate();

        //增加拖动源
        SecDragSourceDO sds = new SecDragSourceDO();
        sds.setUserId(userId);
        sds.setEpId(dragSourceTempDO.getEpId());
        sds.setSecDragSourceTempDO(dragSourceTempDO);
        sds.setVisible('0');
        sds.setTitle(dragSourceTempDO.getTitle());
        sds.setType(dragSourceTempDO.getType());
        sds.setSecDragTargetDO(dragTargetDO);
        sds.setOrderNum(orderNum);
        this.doSave(sds);
    }


    /**
     * 功能描述:更新拖动源
     * @param dragSourceId 拖动源标识
     * @param dragTargetDO 容器对象
     * @param dragSourceTempDO 拖动源模板对象
     * @param userId 用户标识
     * @param int 顺序号
     * @return 无
     */
    public void updateDragSource(Long dragSourceId, SecDragTargetDO dragTargetDO
            , SecDragSourceTempDO dragSourceTempDO, int orderNum, Long userId){

        SecDragSourceDO oldSds = this.findById(dragSourceId);
        if (oldSds != null){

        	/*
               如果不是同一容器的话,大于旧拖动源顺序号的-1
               大于新顺序号的拖动源 +1
            */

        	//调整传入的顺序号
            int adjustOrderNum = this.adjustOrderNum(userId, dragSourceTempDO.getEpId()
        			, dragTargetDO.getDragTargetId(), orderNum);

            System.out.println("adjustOrderNum:" + adjustOrderNum);

        	if (!oldSds.getSecDragTargetDO().getDragTargetId()
                    .equals(dragTargetDO.getDragTargetId())){

                StringBuffer updateOldTargetHql = new StringBuffer();
                updateOldTargetHql.append("UPDATE SecDragSourceDO sds ");
                updateOldTargetHql.append("SET sds.orderNum = sds.orderNum - 1 ");
                updateOldTargetHql.append("WHERE sds.orderNum > ? ");
                updateOldTargetHql.append("AND sds.userId = ? ");
                updateOldTargetHql.append("AND sds.epId = ? ");
                updateOldTargetHql.append("AND sds.secDragTargetDO = ? ");

                Query query = getSession().createQuery(updateOldTargetHql.toString());
                query.setParameter(0, orderNum);
                query.setParameter(1, userId);
                query.setParameter(2, dragSourceTempDO.getEpId());
                query.setParameter(3, oldSds.getSecDragTargetDO());
                query.executeUpdate();

                //更新新容器拖动源
                StringBuffer updateNewTargetHql = new StringBuffer();
                updateNewTargetHql.append("UPDATE SecDragSourceDO sds ");
                updateNewTargetHql.append("SET sds.orderNum = sds.orderNum + 1 ");
                updateNewTargetHql.append("WHERE sds.orderNum >= ? ");
                updateNewTargetHql.append("AND sds.userId = ? ");
                updateNewTargetHql.append("AND sds.epId = ? ");
                updateNewTargetHql.append("AND sds.secDragTargetDO = ? ");

                Query query2 = getSession().createQuery(updateNewTargetHql.toString());
                query2.setParameter(0, adjustOrderNum);
                query2.setParameter(1, userId);
                query2.setParameter(2, dragSourceTempDO.getEpId());
                query2.setParameter(3, dragTargetDO);
                query2.executeUpdate();

            } else {
            	//向下拉的情况
            	if (adjustOrderNum > oldSds.getOrderNum()){
            		System.out.println("uptola");
	            	StringBuffer updateTargetHql = new StringBuffer();
	            	updateTargetHql.append("UPDATE SecDragSourceDO sds ");
	            	updateTargetHql.append("SET sds.orderNum = sds.orderNum - 1 ");
	            	updateTargetHql.append("WHERE sds.orderNum > ? ");
	            	updateTargetHql.append("AND sds.orderNum <= ? ");
	            	updateTargetHql.append("AND sds.userId = ? ");
	            	updateTargetHql.append("AND sds.epId = ? ");
	            	updateTargetHql.append("AND sds.secDragTargetDO = ? ");

	            	Query query = getSession().createQuery(updateTargetHql.toString());
	            	query.setParameter(0, oldSds.getOrderNum());
	            	query.setParameter(1, adjustOrderNum);
	            	query.setParameter(2, userId);
	            	query.setParameter(3, dragSourceTempDO.getEpId());
	                query.setParameter(4, dragTargetDO);
	            	query.executeUpdate();
            	} else {
            		//向上拉的情况
            		System.out.println("downtuola");
            		StringBuffer updateTargetHql = new StringBuffer();
	            	updateTargetHql.append("UPDATE SecDragSourceDO sds ");
	            	updateTargetHql.append("SET sds.orderNum = sds.orderNum + 1 ");
	            	updateTargetHql.append("WHERE sds.orderNum < ? ");
	            	updateTargetHql.append("AND sds.orderNum >= ? ");
	            	updateTargetHql.append("AND sds.userId = ? ");
	            	updateTargetHql.append("AND sds.epId = ? ");
	            	updateTargetHql.append("AND sds.secDragTargetDO = ? ");

	            	Query query = getSession().createQuery(updateTargetHql.toString());
	            	query.setParameter(0, oldSds.getOrderNum());
	            	query.setParameter(1, adjustOrderNum);
	            	query.setParameter(2, userId);
	            	query.setParameter(3, dragSourceTempDO.getEpId());
	                query.setParameter(4, dragTargetDO);
	            	query.executeUpdate();

            	}
            }

        	//更新当前拖动源
        	oldSds.setOrderNum(adjustOrderNum);
        	oldSds.setSecDragSourceTempDO(dragSourceTempDO);
        	oldSds.setSecDragTargetDO(dragTargetDO);
        	this.doSave(oldSds);
        }


    }

    /**
	 * 功能描述:调整顺序号
	 * @param userId 用户标识
	 * @param epId 企业标识
	 * @param dragTargetId 容器标识
	 * @param orderNum 顺序号
	 * @return int
	 */
    @SuppressWarnings("unchecked")
	public int adjustOrderNum(Long userId, Long epId
			, Long dragTargetId, int orderNum){

		int adjustOrderNum = orderNum ;
		Criteria crit = this.getEntityCriteria();
        crit.add(Restrictions.eq("secDragTargetDO.dragTargetId", dragTargetId));
        crit.add(Restrictions.eq("userId", userId));
        crit.add(Restrictions.eq("epId", epId));
        crit.addOrder(Order.desc("orderNum"));
        List<SecDragSourceDO> sameTargetSource = crit.list();
        //顺序号无可能大于现有同一容器的拖动源,如果出现就需要调整顺序号
        if (sameTargetSource != null && sameTargetSource.size() > 0){
            SecDragSourceDO maxOrderNumSds = sameTargetSource.get(0);
            //大于最大的ordernum+1的话,调整为最大,也就是 + 1
            if (adjustOrderNum > maxOrderNumSds.getOrderNum() + 1){
            	adjustOrderNum = maxOrderNumSds.getOrderNum() + 1;
            }
        } else {
            //如果为空,最大不应该大于1,大于1的时候调整为1
            if (adjustOrderNum > 0){
            	adjustOrderNum = 0;
            }
        }

        return adjustOrderNum;

	}

    /**
     * 功能描述:通过拖动源模板和用户号查找拖动源
     * @param userId 用户标识
     * @param dragSourceTempId 拖动源模板标识
     * @param epId 企业标识
     * @return 无
     */
    public SecDragSourceDO searchDragSource(Long userId, String dragSourceTempId,Long epId){

    	 Criteria crit = this.getEntityCriteria();
         crit.add(Restrictions.eq("userId", userId));
         crit.add(Restrictions.eq("secDragSourceTempDO.dragSourceTempId", Long.parseLong(dragSourceTempId)));
         crit.add(Restrictions.eq("epId", epId));

         if (crit.list() !=null && crit.list().size() > 0){
        	 return (SecDragSourceDO)crit.list().get(0);
         }

         return null;

    }




}
